package com.github;

import java.math.BigDecimal;
import java.text.DecimalFormat;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;

import lombok.NonNull;
import lombok.experimental.UtilityClass;

/**
 * @author lijinting01
 *
 */
@UtilityClass
@SuppressWarnings("deprecation")
public class WorkbookCellUtils {

	private static final DecimalFormat NUMBER_FORMAT = new DecimalFormat("0");

	/**
	 * @param cell
	 * @return
	 */
	public static final String asString(@NonNull org.apache.poi.ss.usermodel.Cell cell) {
		final CellType cellType = cell.getCellTypeEnum();
		if (cellType == null) {
			throw new ExcelException();
		}
		switch (cellType) {
		case NUMERIC:
			return NUMBER_FORMAT.format(cell.getNumericCellValue());
		case BOOLEAN:
			return String.valueOf(cell.getBooleanCellValue());
		case STRING:
			return cell.getStringCellValue();
		case BLANK:
			return StringUtils.EMPTY;
		default:
			return null;
		}
	}

	/**
	 * <ul>
	 * <li>如果本身是整型就返回，如果本身是浮点型会损失精度。</li>
	 * <li>如果本身是字符型就转换成整型，如果字符不是有效数字就转换成0</li>
	 * <li>如果本身是布尔型，为真返回1，不为真都返回0</li>
	 * </ul>
	 * 
	 * @param cell
	 * @return
	 */
	public static final Integer asInteger(@NonNull org.apache.poi.ss.usermodel.Cell cell) {
		final CellType cellType = cell.getCellTypeEnum();
		if (cellType == null) {
			throw new ExcelException();
		}
		switch (cellType) {
		case NUMERIC:
			return Integer.valueOf((int) cell.getNumericCellValue());
		case BOOLEAN:
			return cell.getBooleanCellValue() == Boolean.TRUE.booleanValue() ? 1 : 0;
		case STRING:
			return StringUtils.isNumeric(cell.getStringCellValue()) ? Integer.valueOf(cell.getStringCellValue()) : 0;
		case BLANK:
			return 0;
		default:
			return null;
		}
	}

	/**
	 * @param cell
	 * @return
	 */
	public static final Boolean asBoolean(@NonNull Cell cell) {
		final CellType cellType = cell.getCellTypeEnum();
		if (cellType == null) {
			throw new ExcelException();
		}
		switch (cellType) {
		case NUMERIC:
			return cell.getNumericCellValue() != 0L;
		case BOOLEAN:
			return cell.getBooleanCellValue();
		case STRING:
			return (StringUtils.isNumeric(cell.getStringCellValue()) ? Integer.valueOf(cell.getStringCellValue())
					: 0) != 0;
		default:
			return false;
		}
	}

	/**
	 * 
	 * 
	 * @param cell
	 * @return
	 */
	public static final Double asDouble(@NonNull org.apache.poi.ss.usermodel.Cell cell) {
		final CellType cellType = cell.getCellTypeEnum();
		if (cellType == null) {
			throw new ExcelException();
		}
		switch (cellType) {
		case NUMERIC:
			return Double.valueOf(cell.getNumericCellValue());
		case BOOLEAN:
			return cell.getBooleanCellValue() == Boolean.TRUE.booleanValue() ? Double.valueOf(1) : Double.valueOf(0);
		case STRING:
			return StringUtils.isNumeric(cell.getStringCellValue()) ? Double.valueOf(cell.getStringCellValue())
					: Double.valueOf(0);
		case BLANK:
			return Double.valueOf(0);
		default:
			return null;
		}
	}

	/**
	 * 
	 * 
	 * @param cell
	 * @return
	 */
	public static final BigDecimal asBigDecimal(@NonNull org.apache.poi.ss.usermodel.Cell cell) {
		final CellType cellType = cell.getCellTypeEnum();
		if (cellType == null) {
			throw new ExcelException();
		}
		switch (cellType) {
		case NUMERIC:
			return BigDecimal.valueOf(cell.getNumericCellValue());
		case BOOLEAN:
			return cell.getBooleanCellValue() == Boolean.TRUE.booleanValue() ? BigDecimal.ONE : BigDecimal.ZERO;
		case STRING:
			return StringUtils.isNumeric(cell.getStringCellValue())
					? BigDecimal.valueOf(Long.valueOf(cell.getStringCellValue())) : BigDecimal.ZERO;
		case BLANK:
			return BigDecimal.ZERO;
		default:
			return null;
		}
	}
}
